package rating

import (
	"fmt"
	"github.com/templui/templui/internal/components/icon"
	"github.com/templui/templui/internal/utils"
	"strconv"
)

type Style string

const (
	StyleStar  Style = "star"
	StyleHeart Style = "heart"
	StyleEmoji Style = "emoji"
)

type Props struct {
	ID          string
	Class       string
	Attributes  templ.Attributes
	Value       float64
	ReadOnly    bool
	Precision   float64
	Name        string
	Form        string
	OnlyInteger bool
}

type GroupProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

type ItemProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
	Value      int
	Style      Style
}

templ Rating(props ...Props) {
	{{ var p Props }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	{{ p.setDefaults() }}
	<div
		if p.ID != "" {
			id={ p.ID }
		}
		data-tui-rating-component
		data-tui-rating-initial-value={ fmt.Sprintf("%.2f", p.Value) }
		data-tui-rating-precision={ fmt.Sprintf("%.2f", p.Precision) }
		data-tui-rating-readonly={ strconv.FormatBool(p.ReadOnly) }
		if p.Name != "" {
			data-tui-rating-name={ p.Name }
		}
		data-tui-rating-onlyinteger={ strconv.FormatBool(p.OnlyInteger) }
		class={
			utils.TwMerge(
				"flex flex-col items-start gap-1",
				p.Class,
			),
		}
		{ p.Attributes... }
	>
		{ children... }
		if p.Name != "" {
			<input
				type="hidden"
				name={ p.Name }
				value={ fmt.Sprintf("%.2f", p.Value) }
				if p.Form != "" {
					form={ p.Form }
				}
				data-tui-rating-input
			/>
		}
	</div>
}

templ Group(props ...GroupProps) {
	{{ var p GroupProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	<div
		if p.ID != "" {
			id={ p.ID }
		}
		class={ utils.TwMerge("flex flex-row items-center gap-1", p.Class) }
		{ p.Attributes... }
	>
		{ children... }
	</div>
}

templ Item(props ...ItemProps) {
	{{ var p ItemProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	{{ p.setDefaults() }}
	<div
		if p.ID != "" {
			id={ p.ID }
		}
		data-tui-rating-item
		data-tui-rating-value={ strconv.Itoa(p.Value) }
		class={
			utils.TwMerge(
				"relative",
				colorClass(p.Style),
				"transition-opacity",
				"cursor-pointer", // Default cursor
				p.Class,
			),
		}
		{ p.Attributes... }
	>
		<div class="opacity-30">
			@ratingIcon(p.Style, false, float64(p.Value))
		</div>
		<div
			class="absolute inset-0 overflow-hidden w-0"
			data-tui-rating-item-foreground
		>
			@ratingIcon(p.Style, true, float64(p.Value))
		</div>
	</div>
}

func colorClass(style Style) string {
	switch style {
	case StyleHeart:
		return "text-destructive"
	case StyleEmoji:
		return "text-yellow-500"
	default:
		return "text-yellow-400"
	}
}

func ratingIcon(style Style, filled bool, value float64) templ.Component {
	if style == StyleEmoji {
		if filled {
			switch {
			case value <= 1:
				return icon.Angry()
			case value <= 2:
				return icon.Frown()
			case value <= 3:
				return icon.Meh()
			case value <= 4:
				return icon.Smile()
			default:
				return icon.Laugh()
			}
		}
		return icon.Meh()
	}
	iconProps := icon.Props{}
	if filled {
		iconProps.Fill = "currentColor"
	}
	switch style {
	case StyleHeart:
		return icon.Heart(iconProps)
	default:
		return icon.Star(iconProps)
	}
}

func (p *ItemProps) setDefaults() {
	if p.Style == "" {
		p.Style = StyleStar
	}
}

func (p *Props) setDefaults() {
	if p.Precision <= 0 {
		p.Precision = 1.0
	}
}
